

#ifndef __ACL_MGR_H__
#define __ACL_MGR_H__


//#define __SWIFT_DEBUG__
//#define __SWIFT_BITMAP__
//#define __VALGRIND_DEBUG__

#define  IPV4_MAX_LEN           15
#define  BITMAP_UNIT_SIZE       32

#define  PRIORITY_SWIFT         101
#define  PRIORITY_ACLMGR        102

#define  MATCH_NONE             { "", RULE_INVALID_PRIORITY, ACTION_DENY }

typedef struct tagRBT_OBJECT
{
	struct rb_node stNode;
	unsigned int uiObject;
} RBT_OBJECT_S;

typedef struct tagIPV4_RANGE
{
    unsigned int ipStart;
    unsigned int ipEnd;
} IPV4_RANGE_S;

typedef struct tagRBT_IPV4
{
	struct rb_node stNode;
	IPV4_RANGE_S stIpv4;
} RBT_IPV4_S;

typedef struct tagRULE
{
    struct list_head stNode;
    unsigned int uiPriority;
    unsigned int uiKeyMask;
    ACTION_E enAction;
    struct rb_root stSrcIPv4Rbt;
    struct rb_root stDstIPv4Rbt;
    //struct rb_root astObject[OBJECT_MAX];
    char szRuleName[RULE_NAME_MAXLEN+1];
} RULE_S;

extern pthread_rwlock_t lockEdit;
static inline void EDIT_LOCK_INIT()
{
    pthread_rwlock_init(&lockEdit, NULL); 
}
static inline void EDIT_LOCK_READ()
{
    pthread_rwlock_rdlock(&lockEdit);
}
static inline void EDIT_LOCK_WRITE()
{
    pthread_rwlock_wrlock(&lockEdit);
}
static inline void EDIT_UNLOCK()
{
    pthread_rwlock_unlock(&lockEdit);
}
static inline void EDIT_LOCK_DESTROY()
{
    pthread_rwlock_destroy(&lockEdit);
}

extern pthread_rwlock_t lockMatch;
static inline void MATCH_LOCK_INIT()
{
    pthread_rwlock_init(&lockMatch, NULL); 
}
static inline void MATCH_LOCK_READ()
{
    pthread_rwlock_rdlock(&lockMatch);
}
static inline void MATCH_LOCK_WRITE()
{
    pthread_rwlock_wrlock(&lockMatch);
}
static inline void MATCH_UNLOCK()
{
    pthread_rwlock_unlock(&lockMatch);
}
static inline void MATCH_LOCK_DESTROY()
{
    pthread_rwlock_destroy(&lockMatch);
}

extern void* RBT_Ipv4NodeAlloc(unsigned int ipStart, unsigned int ipEnd);
extern int RBT_Ipv4NodeCompare(struct rb_node *pstNew, const struct rb_node *pstMember);
extern void RBT_Ipv4NodeFree(struct rb_node *pNode);
extern struct list_head* RULE_LIST();

static inline void ipv4_to_string(unsigned int ip_addr, char *pcResult, unsigned int uiBufLen)
{
    pcResult[0] = 0;
    inet_ntop(AF_INET, &ip_addr, pcResult, uiBufLen);
}

static inline void* zalloc(unsigned int uiSize)
{
	void *buffer = NULL;
#ifdef __VALGRIND_DEBUG__
    if (__VALGRIND_FLAG__) return NULL;
#endif
    buffer = malloc(uiSize);
	if (buffer)
	{
		memset(buffer, 0, uiSize);
	}
	return buffer;
}

static inline size_t strlcpy(char *dst, const char *src, size_t size)
{
    char* d = dst;
    const char* s = src;
    size_t n = size;

    if (s == 0 || d == 0) return 0;

    /* Copy as many bytes as will fit */
    if (n != 0 && --n != 0)
    {
        do
        {
            if ((*d++ = *s++) == 0) 
                break;
        } while (--n != 0);
    }

    /* Not enough room in dst, add NUL and traverse rest of src */
    if (n == 0)
    {
        if (size != 0)
        *d = '\0';                /* NUL-terminate dst */
        while (*s++)
            ;
    }

    return(s - src - 1);        /* count does not include NUL */
}

#endif

